﻿using System;
using System.Collections.Generic;
using System.Linq;

namespace Soul.XLS
{
    public class ExcelRow
    {
        private ExcelTable Table { get; }

        public int? Height { get; set; }

        public List<ExcelCell> Cells { get; private set; }

        public IReadOnlyCollection<ExcelColumn> Columns => Table.Columns;

        public ExcelRow(ExcelTable table)
        {
            Table = table;
            Cells = Columns.Select(s => new ExcelCell(s, null)).ToList();
        }

        public void SetFormula(string code, string formula)
        {
            this[code] = new ExcelFormula(formula);
        }

        public object this[string code]
        {
            get
            {
                var cell = GetCell(code);
                return cell?.Value; ;
            }

            set
            {
                var cell = GetCell(code);
                if (cell != null)
                {
                    cell.Value = value;
                }
            }
        }

        private ExcelCell GetCell(string code)
        {
            var cell = Cells.Where(a => a.Column.Code == code).FirstOrDefault();
            return cell;
        }

        public T GetValue<T>(string code)
        {
            var value = GetCell(code).Value;
            if (value == null)
            {
                return default;
            }
            var type = Nullable.GetUnderlyingType(typeof(T)) == null ? typeof(T) : Nullable.GetUnderlyingType(typeof(T));
            if (type == typeof(DateTime))
            {
                object result = DateTime.Parse(value.ToString());
                return (T)result;
            }
            return (T)Convert.ChangeType(value, type);
        }

        public DateTime? GetDateTimeValue(string code, string format)
        {
            var value = GetCell(code).Value;
            if (value == null)
            {
                return default;
            }
            if (value is DateTime)
            {
                return (DateTime)value;
            }
            if (DateTime.TryParse(value.ToString(), out DateTime result))
            {
                return result;
            }
            return DateTime.ParseExact(value.ToString(), format, System.Globalization.CultureInfo.CurrentCulture);
        }
    }
}
